#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*Define of our Global Variables*/
#define P_SIZE 500
#define W_SIZE 30

/*
 * Function: ClearString
 * Params: char *String
 * return: VOID
 * Clean the String
 */
void *ClearString(char *String);

/*
 * Function: W_isPalindrome
 * Params: char *String
 * return: int: 1 - TRUE; 0 - FALSE
 * Verify if the String received is a palindrome.
 * There's only one difference between this function and the P_isPalindrome:
 * Here we use an array of W_SIZE = 30 and the other uses P_SIZE = 500
 */
int W_isPalindrome(char *String);

/*
 * Function: P_isPalindrome
 * Params: char *String
 * return: int: 1 - TRUE; 0 - FALSE
 * Verify if the String received is a palindrome.
 * There's only one difference between this function and the W_isPalindrome:
 * Here we use an array of W_SIZE = 500 and the other uses W_SIZE = 30
 */
int P_isPalindrome(char *String);

/*
 * Function: inEndOfPhrase
 * Param: char c
 * return int: 1 _ TRUE; 0 - FALSE
 * Verify if the char indicates an end of phrase
*/
int isEndOfPhrase(char c);

/*
 * Function: inEndOfWord
 * Param: char c
 * return int: 1 _ TRUE; 0 - FALSE
 * Verify if the char indicates an end of word
*/
int isEndOfWord(char c);

/*
 * Function: inTheWord
 * Param: char c
 * return int: 1 _ TRUE; 0 - FALSE
 * Verify if the char is in the word
*/
int inTheWord(char c);

/*
 * Function: CountPalindrome
 * Param: FILE *f
 * return: INT array: One array with the number of palindromes found
                      [0] Number of Palindrome words
                      [1] Number of Palindrome phrases
 * Verify if each word and sentence from the file is a palindrome.
*/
void CountPalindrome(char *StringTemp, long int sizeFile, int numberOfPalindromes[]);

int main(){
    //Create and set the varibles and open the input File
    FILE *f = fopen("shakespe.txt", "r");
    int n[2];
    int counter=0;
    char *StringTemp;
    long int sizeFile;
    //Verify if the file oppened
    if(f == NULL){
        printf("Cannot open file\n");
        exit(-1);
    }
    else{
		//Allocs space enough to load the whole file in the String
        fseek (f, 0, SEEK_END);
        sizeFile = ftell(f);
        rewind(f);
        StringTemp = (char*)malloc(sizeFile*sizeof(char));
        fread(StringTemp, sizeof(char), sizeFile, f);

        // Start the function
        CountPalindrome(StringTemp, sizeFile, n);
        printf("\nPalindromes found:\nWord - %7d\nPhrases - %4d\n\n", n[0], n[1]);
    }

    fclose(f);
    return 0;
}

void *ClearString(char *String){
    //Gets the size of the string and change every char for a '\0'
    int i, size = strlen(String);
    for(i=0; i< size; i++){
        String[i] = '\0';
    }
}

int W_isPalindrome(char *String){
    // We create the local variables and set the initial values
    char inverse_String[W_SIZE];
    int count, size = strlen(String);
    int i;
    count = size-1;
    ClearString(inverse_String);

    // If the String isn't just a letter, i.e: 'a', verify if its a palindrome
    if(strlen(String) > 1){
        //transform all the letters to lower chars
        for(i=0; i<size; i++){
            String[i] = tolower(String[i]);
        }

        //copy the string to a aux string in the inverse
        for(i=0; i<size; i++){
            inverse_String[i] = String[count];
            count--;
        }
        //compare both strings
        if(strcmp(inverse_String, String) == 0){
            return 1;
        }
        else{
            return 0;
        }
    }
    else return 0;
}

int P_isPalindrome(char *String){
    // We create the local variables and set the initial values
    char inverse_String[P_SIZE];
    int count, size = strlen(String);
    int i;

    count = size-1;
    ClearString(inverse_String);

    // If the String isn't just a letter, i.e: 'a', verify if its a palindrome
    if(strlen(String) > 1){
        //transform all the letters to lower chars
        for(i=0; i<size; i++){
            String[i] = tolower(String[i]);
        }

        //copy the string to a aux string in the inverse
        for(i=0; i<size; i++){
            inverse_String[i] = String[count];
            count--;
        }

        //compare both strings
        if(!strcmp(inverse_String, String)){
            return 1;
        }
        else{
            return 0;
        }
    }
    else return 0;
}

int isEndOfPhrase(char c){
    //if the char is one of this symbols, its an end of phrase
    if(c == '.' || c == ';' || c == '(' || c == ')' || c == '"' ||
       c == ':' || c == '<' || c == '>' || c == '{' || c == '}' ||
       c == '[' || c == ']' || c == '|' || c == '&' || c == '!' ||
       c == '?' || c == '\n'|| c == '\t'|| c == '\r' )
       return 1;
    else return 0;

}

int isEndOfWord(char c){
    //if the char is one of this symbols, its just an end of word
    if(c == ' ' || c == ',' || c == '-' || c == '_'  || c == 39)
        return 1;
    else return 0;
}

int inTheWord(char c){
    //if the char is one of this symbols, its not the final of the word
    if(((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')))
        return 1;
    else return 0;

}

void CountPalindrome(char *StringTemp, long int sizeFile, int numberOfPalindromes[]){
    // Create and Set the variables and its initials values
    char Word[W_SIZE];
    char Phrase[P_SIZE];
    char c;
    int counter=0;
    long int i;

    numberOfPalindromes[0] = 0;
    numberOfPalindromes[1] = 0;

    ClearString(Word);

    // For each char of the file, analyses if indicates an end of word, phrase or is in the middle of word
    for(i=0; i<sizeFile; i++){
        c = StringTemp[i];
        //If it is a letter or number, continue the analysis
        if( inTheWord(c) ){
            Word[counter] = c;
            counter++;
        }
        //If it is just an end of word, verify if is a palindrome
        else if( isEndOfWord(c) ){
            strcat(Phrase, Word);
            if(W_isPalindrome(Word) && strlen(Word) > 1){
                numberOfPalindromes[0]++;
            }

            ClearString(Word);
            counter=0;
        }
        //If is an end of Phrase, verify if the last word is a palindrome and then verify if the phrase is a palindrome
        else if( isEndOfPhrase(c) ){

            strcat(Phrase, Word);

            if(W_isPalindrome(Word) && strlen(Word) > 1){
                numberOfPalindromes[0]++;
            }

            if(P_isPalindrome(Phrase) && strlen(Phrase) > 1){
                numberOfPalindromes[1]++;
            }
            ClearString(Word);
            ClearString(Phrase);
            counter = 0;
        }
    }
}










